<?php
/**
 * @author Eugenio Fage
 * http://eugeniofage.wordpress.com/
 * http://code.google.com/p/monky/
 * 
 */
class UsersController extends AppController {

	var $name = 'Users';
	var $uses = array('User','Log');
	
	var $components=array('RequestHandler');
	

	function beforeFilter(){
		parent::beforeFilter();
		
		if(($this->action=='login')&&($this->Log->getWrongLogins(Visitor::ip_int(),20)>8)){
			$this->Session->setFlash(__('You have been temporaly ban for 20 minutes... sorry',true));
			$this->redirect(array('controller'=>'links','action'=>'index'));
		}
		
		$this->Auth->deny('edit');
	}
		
	function index() {
		$this->redirect(array('controller'=>'links','action'=>'index'));
	}

	function view($id = null) {
		$user=$this->_getUser($id,array('Group.name'));
		$user['User']['ranking']=$this->User->getRanking($id);
		$this->set(compact('user'));
	}
	
	function profile(){
		 $this->redirect(array('action'=>'view',$this->Auth->user('id')));
	}

	function edit(){
		
	}
	
	function links($id=null){
		$user=$this->_getUser($id);
		$this->paginate['Link']=array(
			'conditions'=>array('Link.user_id'=>$user['User']['id']),
			'fields'=>array('Link.id','Link.type','Link.status','Link.status_modified','Link.comment_status','Link.votes','Link.negatives', 'Link.anonymous', 'Link.karma', 'Link.modified','Link.url','Link.thumb', 'Link.title', 'Link.content','Link.comment_count'),
			'contain' => array('Category'=>array('id','name')),
			'order'=>array('Link.id'=>'DESC'),
			'limit' => 20
		);
		$links=$this->paginate($this->User->Link);
		
		$linksGetVoteValue=array();
		
		foreach ($links as $id=>$link){
			$links[$id]['Category']['Parent']=$this->User->Link->Category->getparentnode($link['Category']['id'],array('id','name'));			
			if($links[$id]['isVotable']=$this->User->Link->isVotable($link,$this->Auth->user())){
				$linksGetVoteValue[$id]=$link['Link']['id'];
				$voteValues=$this->User->Link->Vote->getLinksVoteValue($linksGetVoteValue,$this->Auth->user('id'));
				foreach ($voteValues as $pos=>$value) {
					$links[$pos]['voteValue']=$value;
				}
			}
		}
		
		$this->set(compact('user','links'));
	}
	
	function login(){
		if($this->Log->getWrongLogins(Visitor::ip_int(),20)>5){
			$this->Session->setFlash(__('Be carefull, you have try to login for several times... you could be banned',true));
		}
		
		// check if user has login
		if($this->Session->check('Auth.User')){
			$this->_afterLogin($this->data);
		}
		
		// try to login using cookie
		$cookie = $this->Cookie->read('Auth.User');
		if (empty($this->data)&&!is_null($cookie)) {
			if ($this->Auth->login($cookie)) {
				$this->_afterLogin();
			}
			$this->Session->delete('Message.auth');
		}
				
		// enter when a wrong login occur
		if($this->Session->check('Message.auth')){
			$this->_loginFail();
		}
	}
	
	public function facebook_connect() {
		App::import('Vendor', 'FbSingleton', array('file' => 'facebook'.DS.'fb_singleton.php'));
		
		$fb=FbSingleton::getInstance();
		
		$session = $fb->getSession();
		if ($session) {
  			$fbuid=$fb->getUser();
    	}
		
    	if (!$session) {
        	$this->redirect($fb->getLoginUrl(array('canvas'=> 0,'fbconnect' => 1,'callback'=>Router::url(array('controller'=>'users','action'=>'facebook_register'),true))));
    	}		
   		
    	$this->_loginThirdPartyUser($session['uid'].'@facebook.com');
    	
    	$this->redirect(Router::url(array('controller'=>'users','action'=>'facebook_register'),true));
	}
	
	public function facebook_register() {
		$this->_beforeRegister();
		
		App::import('Vendor', 'FbSingleton', array('file' => 'facebook'.DS.'fb_singleton.php'));
		$fb=FbSingleton::getInstance();
		$session = $fb->getSession();
		if(!$session){
			$this->redirect(Router::url(array('controller'=>'users','action'=>'facebook_connect'),true));
		}
		
		$this->_registerThirdPartyUser($session['uid'].'@facebook.com');
		
		
	}
		
	public function twitter_connect() {
		
		//check if user has already give permission from twitter
		if($this->Cookie->read('twitterSecret')==Security::hash(serialize($this->Cookie->read('twitterUser')))){
    		$this->redirect(array('action'=>'twitter_register'));
    	}
		
		App::import('Vendor', 'oauth', array('file' => 'oauth'.DS.'oauth_consumer.php'));
		$consumer = new OAuth_Consumer(Configure::read('Twitter.key'),Configure::read('Twitter.secret'));
        $requestToken = $consumer->getRequestToken('http://twitter.com/oauth/request_token', Router::url(array('controller'=>'users','action'=>'twitter_callback'),true));
      	$this->Session->write('twitter_request_token', array('key'=>$requestToken->key, 'secret'=>$requestToken->secret));
              
        $this->redirect('http://twitter.com/oauth/authorize?oauth_token=' . $requestToken->key);
    }

    public function twitter_callback() {
    	App::import('Vendor', 'oauth', array('file' => 'oauth'.DS.'oauth_consumer.php'));
    	$requestToken = $this->Session->read('twitter_request_token');
    	$requestToken=new OAuthToken($requestToken['key'], $requestToken['secret']);   	
    	
        $consumer = new OAuth_Consumer(Configure::read('Twitter.key'),Configure::read('Twitter.secret'));
        $accessToken = $consumer->getAccessToken('http://twitter.com/oauth/access_token', $requestToken);

        @parse_str($consumer->getFullResponse(),$parsed);
        if(!isset($parsed['user_id'])|| !$parsed['user_id']){
        	$this->cakeError('monkyError', array('title'=>__('Twitter error!',true),'message'=> __('There has been an error with the twitter api... ',true).$consumer->getFullResponse()));
        }
        
        extract($parsed);
        $twitter_user=compact('user_id','screen_name');
                
        $this->Cookie->write('twitterUser',$twitter_user,true);
        $this->Cookie->write('twitterSecret',Security::hash(serialize($twitter_user)));
        
        $this->_loginThirdPartyUser($twitter_user['user_id'].'@twitter.com');
        
        $this->redirect(array('action'=>'twitter_register'));
    }
    
    function twitter_register(){
    	$this->_beforeRegister(false);
    	$twitter_user=$this->Cookie->read('twitterUser');
    	
        
    	if(!$twitter_user || $this->Cookie->read('twitterSecret')!=Security::hash(serialize($twitter_user))){
    		$this->redirect(array('action'=>'twitter_connect'));
    	}
    	    	    	
    	$this->_registerThirdPartyUser($twitter_user['user_id'].'@twitter.com');
    	
    }
    
	function logout(){
		$this->Cookie->destroy('User');
		$this->redirect($this->Auth->logout());
	}

	function confirm($id=null,$hash=null){
		if(!$id||!$hash) {
			$this->redirect(array('controller'=>'users','action'=>'login'));
		}
		$this->User->recursive=-1;
		$this->User->id=$id;
		
		$user=$this->User->read(array('validated','created','username','password','email'));
		
		if($hash!=Security::hash($this->User->id.$user['User']['username'].$user['User']['created'],'md5',true)){
			$this->Session->setFlash(__('Invalid hash', true));
			$this->redirect(array('controller'=>'users','action'=>'login'));
		}elseif(!$user['User']['validated']){
			$this->Session->setFlash(__('Congratulations! You have register successful', true));
			$this->User->saveField('validated',true);
			$this->Log->save(array('Log'=>array('type'=>'user_new','user_id'=>$this->User->id)));
			$this->Auth->login($user);
			$this->_afterLogin($user);
		}
		
		$this->redirect(array('controller'=>'users','action'=>'login'));
	}
		
	function register(){
		$this->_beforeRegister();			
		if ($this->data) {
						
			$this->User->validate['password']['compare']= array(
        		'rule' => array('equalTo', $this->Auth->password($this->data['User']['passwordconfirmation'])),  
        		'message' => 'La confirmacion del password no coincide'
        	);
       	   	
        	// add user ip and set the last time of calculated karma
    		$this->data['User']=am($this->data['User'],array('ip'=>Visitor::ip_int(),'karma_time_calculated'=>getTimestamp()));
    		
        	$this->User->create($this->data);
        	if($this->User->save(null,true,array('username','ip','password','email','karma_time_calculated'))){
        	$this->_sendRegisterMail();
        		$this->redirect(array('controller'=>'pages','action'=>'display','user_register'));
        	}
        	        	
        	$this->data['User']['password']=$this->data['User']['passwordconfirmation']='';
    	}
	}
	
	function remind(){
		
	}
	
	/**
	 * 
	 * send the mail con finish with the register process
	 */
	function _sendRegisterMail(){
		$this->_loadComponent('Email');		
		
		$this->Email->to = $this->User->field('email');
		$this->Email->subject = __('Welcome!',true);
		$this->Email->from = 'Cool Web App <app@ejemplo.com>';
		$this->Email->template = 'register';
		$this->Email->sendAs = 'text';
		
		$id=$this->User->id;
		$username=$this->User->field('username');
		$hash=Security::hash($this->User->id.$username.$this->User->field('created'),'md5',true);
		
		$this->set(compact('id','hash','username'));
		//$this->Email->delivery = 'debug';
		
		$this->Email->send();
		
	}
	
	function _beforeRegister($alertMessage=true){
		if($alertMessage&&$this->Session->check('Auth.User')){
			$this->Session->setFlash(__('Hey!, you have register already!', true));
			$this->redirect(array('controller'=>'links','action' => 'index'));
		}		
		
		if($this->User->getUserSignupsFromIp(Visitor::ip_int())>2){
			$this->Session->setFlash(__('Hey, you have to wait 24 hours to sign up again', true));
			$this->redirect(array('controller'=>'links','action' => 'index'));
		}
		
	}

	function _registerThirdPartyUser($email){
		$this->_loginThirdPartyUser($email);
		
		$user['User']=array(
			'username'=>($this->data['User']['username']),
    		'email'=> $email,
    		'password'=>Security::hash(md5(uniqid(mt_rand(), true))),
			'ip'=>Visitor::ip_int(),
    		'validated'=>1,
    		'karma_time_calculated'=>getTimestamp()
    	);
    	    	    	
        $this->User->create($user);
        if(!$this->User->validates(array('fieldList' => array('email','username')))) {
        	return;
        }
        
        if($this->User->save(null,false,array('username','validated','ip','password','email','karma_time_calculated'))){
        	$this->Log->save(array('Log'=>array('type'=>'user_new','user_id'=>$this->User->id)));
        	$this->_loginThirdPartyUser($email);
        }
	}
	
	function _loginThirdPartyUser($email){
    	$user=$this->User->find('first',array(
        	'fields'=>array('User.email','User.password'),
        	'conditions'=>array('User.email'=>$email)
        ));
        
        
        if(!empty($user)){
        	$this->Auth->login($user);
        	$this->Session->delete('Message.auth');
			$this->_afterLogin($this->Auth->user());
        }
    }
	
	/**
	 * 
	 * This will trigger after a user makes a succesful login
	 */
	private function _afterLogin($user=null){
		$loggedId=$this->Auth->user('id');
		
		// is this the first login?
		if(!empty($user)) {
			// insert log
			$userCookie['mail'] = $this->Auth->user('mail');
			$userCookie['password'] = $this->Auth->user('password');
			$this->Cookie->write('Auth.User', $userCookie, true, '+2 weeks');						
		}
		
		
		if(!empty($user)||$this->User->field('ip',array('id'=>$loggedId))!=Visitor::ip_int()){
			//save ip and update last login
			$this->User->updateLastLogin($loggedId);
		}
		
		// check clones and add clone if neccesary 
		$this->User->doClonCheck($loggedId);
		
		if(!$url=$this->Auth->redirect()){
			$url=array('controller'=>'links','action'=>'index');
		}
		
		$this->redirect($this->Auth->redirect());
		
	}
	
	private function _loginFail(){
		$this->Log->save(array('Log'=>array('type'=>'login_failed','extradata'=>Visitor::ip_int())));
	}
	
	function _getUser($id=null,$contain=array()){
		$user=$this->User->find('first',array(
			'conditions'=>array('User.id'=>$id,'User.validated'=>true),
			'contain'=>$contain
		));
		
		if(empty($user)){
			$this->Session->setFlash(__('Invalid user', true));
			$this->redirect(array('controller'=>'links','action' => 'index'));
		}
		
		return $user;
	}
	
}
